package com.ywy.job.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ywy.job.core.JobScheduledRegistrar;
import com.ywy.job.core.JobRunnable;
import com.ywy.job.enums.JobStatusEnum;
import com.ywy.job.mapper.SysJobMapper;
import com.ywy.job.model.SysJob;
import com.ywy.job.rest.PageParam;
import com.ywy.job.rest.PageResult;
import com.ywy.job.service.SysJobService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 任务服务实现
 *
 * @author ywy
 * @date 2021/11/3 16:44
 */
@Service
public class SysJobServiceImpl implements SysJobService {
    @Autowired
    private SysJobMapper jobMapper;
    @Autowired
    private JobScheduledRegistrar jobScheduledRegistrar;

    @Override
    public SysJob getById(Long id) {
        return jobMapper.getById(id);
    }

    @Override
    public PageResult listPage(PageParam param) {
        PageHelper.startPage(param.getPage(), param.getLimit());
        List<SysJob> list = jobMapper.list();
        PageInfo<SysJob> pageInfo = new PageInfo<>(list);
        long total = pageInfo.getTotal();
        return new PageResult(total, list);
    }

    @Override
    public int save(SysJob job) {
        if (job.getId() == null) {
            job.setJobStatus(JobStatusEnum.STOP.getCode());
            job.setCreateUser("admin");
            job.setCreateTime(new Date());
            return jobMapper.insert(job);
        } else {
            SysJob job2 = jobMapper.getById(job.getId());
            // 如果修改任务，且任务状态为运行则不能修改
            if (JobStatusEnum.RUNNING.getCode() ==  job2.getJobStatus()) {
                return -1;
            }
            job.setUpdateUser("admin");
            job.setUpdateTime(new Date());
            return jobMapper.update(job);
        }
    }

    @Override
    public boolean initSchedule() {
        // 获取任务信息数据
        List<SysJob> jobList = jobMapper.list();
        try {
            for (SysJob job : jobList) {
                // 初始化状态为开启的任务
                if (JobStatusEnum.RUNNING.getCode() == job.getJobStatus()) {
                    jobScheduledRegistrar.addJob(job);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Override
    public int run(Long id) {
        SysJob job = jobMapper.getById(id);
        if (job == null) {
            return 0;
        }
        // 如果任务状态为关闭状态则不能立即执行
        if (JobStatusEnum.STOP.getCode() == job.getJobStatus()) {
            return -1;
        }
        try {
            jobScheduledRegistrar.runJobNow(job);
        } catch (Exception e) {
            e.printStackTrace();
            return -2;
        }
        return 1;
    }

    @Override
    public boolean changeStatus(Long id, Integer jobStatus) {
        SysJob job = jobMapper.getById(id);
        if (job == null) {
            return false;
        }
        try {
            // 将任务状态设为相反状态
            if (JobStatusEnum.STOP.getCode() == jobStatus) {
                JobRunnable runnable = new JobRunnable(job.getBeanName(), job.getMethodName(), job.getMethodParams());
                jobScheduledRegistrar.deleteJob(runnable);
                job.setJobStatus(JobStatusEnum.STOP.getCode());
            } else {
                jobScheduledRegistrar.addJob(job);
                job.setJobStatus(JobStatusEnum.RUNNING.getCode());
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return jobMapper.update(job) > 0 ? true : false;
    }

    @Override
    public int delete(Long id) {
        SysJob job = jobMapper.getById(id);
        if (job == null) {
            return 0;
        }
        if (JobStatusEnum.RUNNING.getCode() == job.getJobStatus()) {
            return -1;
        }
        try {
            jobScheduledRegistrar.deleteJob(job);
            return jobMapper.delete(id);
        } catch (Exception e) {
            e.printStackTrace();
            return -2;
        }
    }

    @Override
    public int batchDelete(Long[] ids) {
        // 判断任务是否都停止
        List<SysJob> jobList = new ArrayList<>();
        for (Long id : ids) {
            SysJob job = jobMapper.getById(id);
            if (JobStatusEnum.RUNNING.getCode() == job.getJobStatus()) {
                return -1;
            }
            jobList.add(job);
        }

        for (SysJob job : jobList) {
            try {
                JobRunnable runnable = new JobRunnable(job.getBeanName(), job.getMethodName(), job.getMethodParams());
                jobScheduledRegistrar.deleteJob(runnable);
            } catch (Exception e) {
                e.printStackTrace();
                return -2;
            }
        }
        return jobMapper.batchDelete(ids);
    }
}
